#ifndef WORKER_CHAIN_H_
#define WORKER_CHAIN_H_

#include <Chain.hh>
#include <Lock.hh>
#include <Worker.hh>

typedef USNumber WID;

//
/**
 * \file WorkerChain.hh
 * \author  jsk <jsk.jinsubkim@gmail.com>
 * \version 1.0
 *
 * \class WorkerChain WorkerChain.hh
 *
 * 워커를 리스트로 관리한다.
 * 
 * WorkerChain 클래스는 Chain 클래스를 이용해서 워커를 연결한다.
 * Chain 클래스는 특정 오브젝트가 리스트에 추가되면 해당 오브젝트를 
 * 빼는 것은 불가능하다. 즉, 한번 들어간 오브젝트에 관해서 제어할 수 없다.
 * 
 * 반면에 WorkerChain 클래스는 삽입되는 오브젝트에 대한 아이디를 부여해서
 * 아이디를 통해서 리스트에서 제거하는 방법을 제공한다.
 */
class WorkerChain : protected Chain
{
public:
	/**
	 * \name join
	 * \param NewMember 워커(IWorker).
	 * 
	 * 워커 그룹(IWorkerChain)에 참가한다.
	 * 
	 * 노드(CChainNode)를 생성하고, 그 주소를 Id로 한다.
	 * 노드를 리스트에 포함시킨다.
	 * 
	 * \see createNode, replaceHeader
	 * \return 
	 * 
	 * 성공할 경우 정상적인 Id, 
	 * 실패할 경우 비정상적인 Id.
	 */
	virtual WID join(Worker* NewMember);
	
	/**
	 * \name secede
	 * \param Id 가입할 때 부여 받은 아이디.
	 * 
	 * 워커 그룹(IWorkerChain)에서 탈퇴한다.
	 * 
	 * 제거하려는 노드가 헤더나 테일과 같은지 확인하고,
	 * 같을 경우 헤더나 테일을 갱신하고, 노드를 제거한다.
	 * 
	 * \return
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf secede(WID Id);
	
	/**
	 * \name ban
	 * 
	 * 그룹 맴버 중에 임의로 한명의 아이디를 알려준다.
	 * 
	 * 헤더에 있는 멤버를 가져온다. 헤더 노드를 리스트에서 제거한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 워커의 주소, 
	 * 실패할 경우 NULL.
	 */
	virtual Worker* ban();
	
	/**
	 * \name tellSize
	 * 
	 * 가입자 수를 알려준다.
	 * 
	 * \return 
	 * 
	 * 가입자의 수.
	 */
	virtual USNumber tellSize();
	
// Member
protected:
	
// Constant
public:
	/**
	 * 유효하지 않은 아이디 값.
	 */
	static const USNumber InvalidId = 0;
};

#endif //WORKER_CHAIN_H_